#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>

#include "manager.h"

#define PORT 1234

manager::manager()
{
	score=0;
	speed=1;
	obj_NULL.fix_NULL();
	UI.deletePiece();
	UI.creatPiece(21,38);
	GameLocation.deletePiece();
	GameLocation.creatPiece(20,10);
	Draw_buffer.deletePiece();
	Draw_buffer.creatPiece(20,10);
	Imformation.deletePiece();
	Imformation.creatPiece(8,4);
	Interruption.deletePiece();
	Interruption.creatPiece(3,6);
}

manager::~manager()
{
}

void manager::Menu()
{
	piece choice(3,9);
	int ch=6;

	UI.clearPiece();
	for(int i=12;i<27;i++)	//绘制外框
	{
		UI(i,4)=11;UI(i,20)=11;
	}
	for(int j=5;j<20;j++)
	{
		UI(11,j)=12;UI(27,j)=12;
	}
	UI(11,4)=13;UI(27,4)=14;UI(11,20)=16;UI(27,20)=15;
	UI(16,7)=32;UI(17,7)=9;UI(18,7)=9;UI(19,7)=9;UI(20,7)=9;UI(21,7)=9;UI(22,7)=9;
	UI(16,9)=33;UI(17,9)=9;UI(18,9)=9;UI(19,9)=9;UI(20,9)=9;UI(21,9)=9;UI(22,9)=9;
	UI(16,11)=34;UI(17,11)=9;UI(18,11)=9;UI(19,11)=9;UI(20,11)=9;UI(21,11)=9;UI(22,11)=9;
	UI(16,13)=35;UI(17,13)=9;UI(18,13)=9;UI(19,13)=9;UI(20,13)=9;UI(21,13)=9;UI(22,13)=9;
	UI(16,17)=36;UI(17,17)=9;UI(18,17)=9;UI(19,17)=9;UI(20,17)=9;UI(21,17)=9;UI(22,17)=9;

	for(int i=1;i<8;i++)							//绘制选择框
	{
		choice(i,0)=11;
		choice(i,2)=11;
	}
	choice(0,0)=13;choice(8,0)=14;choice(8,2)=15;choice(0,2)=16;choice(0,1)=12;choice(8,1)=12;

	while(1)
	{
		UI.read_From_soft(choice,15,ch);					//选择框软性写入UI
		clearScreen();
		Draw_UI();
		int key;
		key=readKeyboard(1);
		if(key==DOWN)
		{
			if(ch==6)
				ch=8;
			else if(ch==8)
				ch=10;
			else if(ch==10)
				ch=12;
			else if(ch==12)
				ch=16;
			else
				ch=6;
			for(int n=15;n<24;n++)
			{
				UI(n,6)=0;UI(n,8)=0;UI(n,10)=0;UI(n,12)=0;UI(n,14)=0;UI(n,16)=0;UI(n,18)=0;
			}
			for(int m=6;m<19;m++)
			{
				UI(15,m)=0;UI(23,m)=0;
			}
			UI.read_From_soft(choice,15,ch);					//选择框软性写入UI
			clearScreen();
			Draw_UI();
		}
		else if(key==UP)
		{
			if(ch==6)
				ch=16;
			else if(ch==8)
				ch=6;
			else if(ch==10)
				ch=8;
			else if(ch==12)
				ch=10;
			else
				ch=12;
			for(int n=15;n<24;n++)
			{
				UI(n,6)=0;UI(n,8)=0;UI(n,10)=0;UI(n,12)=0;UI(n,14)=0;UI(n,16)=0;UI(n,18)=0;
			}
			for(int m=6;m<19;m++)
			{
				UI(15,m)=0;UI(23,m)=0;
			}
			UI.read_From_soft(choice,15,ch);					//选择框软性写入UI
			clearScreen();
			Draw_UI();
		}
		else if(key==LIFT||key==RIGHT||key==SPACE)
		{
			if(ch==6)
			{
				if(key==LIFT)				//若左键进入菜单则选择缓慢AI模式
					AIshow(1);
				else
					AIshow(0);
			}	
			else if(ch==8)
				Singleplayer();
			else if(ch==10)
				PlayerVsCPU();
			else if(ch==12)
				Multiplayer();
			else
			{
				clearScreen();
				return;
			}
		}
		else
			continue;

		UI.clearPiece();
		for(int i=12;i<27;i++)	//绘制外框
		{
			UI(i,4)=11;UI(i,20)=11;
		}
		for(int j=5;j<20;j++)
		{
			UI(11,j)=12;UI(27,j)=12;
		}
		UI(11,4)=13;UI(27,4)=14;UI(11,20)=16;UI(27,20)=15;
		UI(16,7)=32;UI(17,7)=9;UI(18,7)=9;UI(19,7)=9;UI(20,7)=9;UI(21,7)=9;UI(22,7)=9;
		UI(16,9)=33;UI(17,9)=9;UI(18,9)=9;UI(19,9)=9;UI(20,9)=9;UI(21,9)=9;UI(22,9)=9;
		UI(16,11)=34;UI(17,11)=9;UI(18,11)=9;UI(19,11)=9;UI(20,11)=9;UI(21,11)=9;UI(22,11)=9;
		UI(16,13)=35;UI(17,13)=9;UI(18,13)=9;UI(19,13)=9;UI(20,13)=9;UI(21,13)=9;UI(22,13)=9;
		UI(16,17)=36;UI(17,17)=9;UI(18,17)=9;UI(19,17)=9;UI(20,17)=9;UI(21,17)=9;UI(22,17)=9;

		GameLocation.clearPiece();
		Imformation.clearPiece();
	}
}

void manager::AIshow(bool mode)
{
	block obj_tmp_turn;				//转向假设
	block obj_tmp_x;				//横向假设
	block obj_tmp_y;				//纵向假设
	block obj_tmp_turn2;				//转向假设2
	block obj_tmp_x2;				//横向假设2
	block obj_tmp_y2;				//纵向假设2
	int mov_turn;
	int mov_x;
	piece GameLocation_tmp(20,10);			//假设游戏区
	piece GameLocation_tmp2(20,10);			//假设游戏区2
	int value_now=0;				//记录当前评价分
	int value_fix=0;
	int value_max=0;				//记录最高评价分
	int value_max_turn;
	int value_max_x;

	int score_add;
	int key;

	Draw_buffer.clearPiece();
	UI.clearPiece();
	score=0;

	int r;
	srand((unsigned)time(NULL));
	r=(rand()%(99));
	obj_now.creatblock(r);
	r=(rand()%(99));
	obj_next.creatblock(r);
	
	for(int i=12;i<27;i++)	//绘制外框
	{
		UI(i,20)=11;
	}
	for(int j=4;j<20;j++)
	{
		UI(11,j)=12;UI(22,j)=12;UI(27,j)=12;
	}
	UI(11,20)=16;UI(22,20)=19;UI(27,20)=15;
	UI(23,16)=30;UI(24,16)=9;UI(25,16)=9;UI(26,16)=9;
	UI(23,18)=31;UI(24,18)=9;UI(25,18)=9;UI(26,18)=9;
	UI(22,10)=20;UI(27,10)=18;UI(22,15)=20;UI(23,15)=11;UI(24,15)=11;UI(25,15)=11;UI(26,15)=11;UI(27,15)=18;
	Imformation(0,4)=11;Imformation(1,4)=11;Imformation(2,4)=11;Imformation(3,4)=11;
	Imformation(0,5)=24;Imformation(1,5)=9;Imformation(2,5)=9;Imformation(3,5)=26;

	while(1)
	{
		value_max=-1000000;
		Imformation.read_From(obj_NULL.getbox(),0,0);
		Imformation.read_From(obj_next.getbox(),obj_next.getx()-3,0);		//将未来积木，分数数等投射到信息区上	
		Imformation(0,7)=27;Imformation(1,7)=9;Imformation(2,7)=9;Imformation(3,7)=28;
		UI.read_From(Imformation,23,6);
		clearScreen();
		Draw_UI();
		key=readKeyboard(0);
		if(key==PAUSE)
		{
			Call_pause(Draw_buffer);
			Draw_buffer.write_To(UI,12,0);
			clearScreen();
			Draw_UI();
			while(readKeyboard(1)!=PAUSE){}
			continue;
		}
		else if(key==LEAVE)
		{
			Call_gameover(Draw_buffer);
			Draw_buffer.write_To(UI,12,0);
			clearScreen();
			Draw_UI();
			while(readKeyboard(1)!=LEAVE){}
			return;
		}

		for(int i=0;i<9;i++)		//是否GAMEOVER
		{
			if(GameLocation(i,3)!=0)
			{
				Call_gameover(Draw_buffer);
				Draw_buffer.write_To(UI,12,0);
				clearScreen();
				Draw_UI();
			while(readKeyboard(1)!=LEAVE){}
			return;
			}
		}
		GameLocation_tmp=GameLocation;
		obj_tmp_turn=obj_now;
		for(mov_turn=0;mov_turn<4;mov_turn++)							//枚举旋转类型
		{
			obj_tmp_x=obj_tmp_turn;
			while(obj_tmp_x.move_lift(GameLocation_tmp)){}
			for(mov_x=obj_tmp_x.getx();/***/;mov_x++)	//枚举横向移动
			{
				obj_tmp_y=obj_tmp_x;
				while(obj_tmp_y.move_down(GameLocation_tmp)){}

				GameLocation_tmp.read_From_soft(obj_tmp_y.getbox(),mov_x,obj_tmp_y.gety());//固化此次枚举类型
				value_fix=Offset(GameLocation_tmp);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
				GameLocation_tmp2=GameLocation_tmp;
				obj_tmp_turn2=obj_next;
				for(int mov_turn2=0;mov_turn2<4;mov_turn2++)
				{
					obj_tmp_x2=obj_tmp_turn2;
					while(obj_tmp_x2.move_lift(GameLocation_tmp2)){}
					for(int mov_x2=obj_tmp_x2.getx();/***/;mov_x2++)	//枚举横向移动
					{
						obj_tmp_y2=obj_tmp_x2;
						while(obj_tmp_y2.move_down(GameLocation_tmp2)){}
						GameLocation_tmp2.read_From_soft(obj_tmp_y2.getbox(),mov_x2,obj_tmp_y2.gety());
						value_now=Evaluation(GameLocation_tmp2)+value_fix*value_fix*10;
/*
						UI.read_From(GameLocation_tmp,12,0);
						clearScreen();
						Draw_UI();
						delay_ms(100);
*/
						if(value_now>value_max)
						{
							value_max=value_now;
							value_max_turn=mov_turn;
							value_max_x=mov_x;
						}
						GameLocation_tmp2=GameLocation_tmp;
						if(!obj_tmp_x2.move_right(GameLocation_tmp2))
							break;
					}
					obj_tmp_turn2.turn(GameLocation_tmp2);
				}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
				GameLocation_tmp=GameLocation;				//取消此次假设固化
				if(!obj_tmp_x.move_right(GameLocation_tmp))
					break;
			}
			obj_tmp_turn.turn(GameLocation_tmp);
		}
		
		for(int i=0;i<value_max_turn;i++)
		{
			Draw_buffer.read_From(GameLocation,0,0);
			obj_now.turn(GameLocation);
			if(mode)
			{
				Draw_buffer.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());
				UI.read_From(Draw_buffer,12,0);
				clearScreen();
				Draw_UI();
				delay_ms(200);
			}	
		}

		while(value_max_x-obj_now.getx()>0)
		{
			Draw_buffer.read_From(GameLocation,0,0);
			obj_now.move_right(GameLocation);
			if(mode)
			{
				Draw_buffer.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());
				UI.read_From(Draw_buffer,12,0);
				clearScreen();
				Draw_UI();
				delay_ms(25);
			}
		}
		while(obj_now.getx()-value_max_x>0)
		{
			Draw_buffer.read_From(GameLocation,0,0);
			obj_now.move_lift(GameLocation);
			if(mode)
			{
				Draw_buffer.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());
				UI.read_From(Draw_buffer,12,0);
				clearScreen();
				Draw_UI();
				delay_ms(25);
			}
		}
		Draw_buffer.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());
		UI.read_From(Draw_buffer,12,0);
		clearScreen();
		Draw_UI();

		while(obj_now.move_down(GameLocation))
		{
			obj_now.move_down(GameLocation);
			Draw_buffer.read_From(GameLocation,0,0);
			if(mode)
			{
				Draw_buffer.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());
				UI.read_From(Draw_buffer,12,0);
				clearScreen();
				Draw_UI();
				delay_ms(25);
			}
		}

		GameLocation.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());//触底则固化该积木
		score_add=Offset(GameLocation);				//判断消行，且获取消行数；
		UI.read_From(GameLocation,12,0);
		switch(score_add)
		{
		case 1:
			score+=1;
			break;
		case 2:
			score+=3;
			break;
		case 3:
			score+=6;
			break;
		case 4:
			score+=10;
			break;
		default:
			break;
		}

		clearScreen();
		Draw_UI();

		obj_now=obj_next;
		r=(rand()%(99));
		obj_next.creatblock(r);
	}
}

void manager::Singleplayer()
{
	int time_piece;
	int player_finish=1;
	int score_add=0;
	int r;
	int s;

	UI.clearPiece();
	score=0;

	srand((unsigned)time(NULL));
	r=(rand()%(99));
	obj_next.creatblock(r);

	for(int i=12;i<27;i++)	//绘制外框
	{
		UI(i,20)=11;
	}
	for(int j=4;j<20;j++)
	{
		UI(11,j)=12;UI(22,j)=12;UI(27,j)=12;
	}
	UI(11,20)=16;UI(22,20)=19;UI(27,20)=15;
	UI(23,16)=30;UI(24,16)=9;UI(25,16)=9;UI(26,16)=9;
	UI(23,18)=31;UI(24,18)=9;UI(25,18)=9;UI(26,18)=9;
	UI(22,10)=20;UI(27,10)=18;UI(22,15)=20;UI(23,15)=11;UI(24,15)=11;UI(25,15)=11;UI(26,15)=11;UI(27,15)=18;
	Imformation(0,4)=11;Imformation(1,4)=11;Imformation(2,4)=11;Imformation(3,4)=11;

	Imformation.read_From(obj_NULL.getbox(),0,0);						//将未来积木，分数等投射到信息区上
	Imformation.read_From(obj_next.getbox(),obj_next.getx()-3,0);
	Imformation(0,5)=24;Imformation(1,5)=9;Imformation(2,5)=9;Imformation(3,5)=25;
	Imformation(0,7)=27;Imformation(1,7)=9;Imformation(2,7)=9;Imformation(3,7)=28;
	UI.read_From(Imformation,23,6);

	for(time_piece=0;/***/;time_piece++)
	{
		for(int i=0;i<9;i++)			//是否GAMEOVER
		{
			if(GameLocation(i,3)!=0)
			{
				Call_gameover(Draw_buffer);
				Draw_buffer.write_To(UI,12,0);
				clearScreen();
				Draw_UI();
				while(readKeyboard(1)!=LEAVE){}
				return;
			}
		}

		if(player_finish==1)		//若一回合结束，则做好下一回合准备
		{
			obj_now=obj_next;
			r=(rand()%(99));
			obj_next.creatblock(r);
			Imformation.read_From(obj_NULL.getbox(),0,0);						//将未来积木，分数等投射到信息区上
			Imformation.read_From(obj_next.getbox(),obj_next.getx()-3,0);
			Imformation(0,7)=27;Imformation(1,7)=9;Imformation(2,7)=9;Imformation(3,7)=28;
			UI.read_From(Imformation,23,6);
			score_add=0;
			player_finish=0;
			continue;
		}
		else
		{
			for(int wait=0;wait<CATCH;wait++)
			{
				Draw_buffer.read_From(GameLocation,0,0);
				s=Frame();
				if(s==1)
				{						
					Call_pause(Draw_buffer);
					Draw_buffer.write_To(UI,12,0);
					clearScreen();
					Draw_UI();
					while(readKeyboard(1)!=PAUSE){}
					continue;
				}
				else if(s==2)
				{
					Call_gameover(Draw_buffer);
					Draw_buffer.write_To(UI,12,0);
					clearScreen();
					Draw_UI();
					while(readKeyboard(1)!=LEAVE){}
					return;
				}
				else if(s==0)
				{
					Draw_buffer.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());//将当前方块位置软性投射到缓冲绘图区
					UI.read_From(Draw_buffer,12,0);			//将缓冲绘图区内容投射到界面上
				}
			}
			if((time_piece+1)%(12-speed)==0)
			{
				if(!obj_now.move_down(GameLocation))
				{
					GameLocation.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());
					score_add=Offset(GameLocation);				//判断消行，且获取消行数
					UI.read_From(GameLocation,12,0);
					switch(score_add)
					{
					case 1:
						score+=1;
						break;
					case 2:
						score+=3;
						break;
					case 3:
						score+=6;
						break;
					case 4:
						score+=10;
						break;
					default:
						break;
					}
					if(score<5)						//根据得分改变速度
						speed=1;
					else if(score<15)
						speed=2;
					else if(score<30)
						speed=3;
					else if(score<50)
						speed=4;
					else if(score<75)
						speed=5;
					else if(score<105)
						speed=6;
					else if(score<140)
						speed=7;
					else if(score<180)
						speed=8;
					else if(score<225)
						speed=9;
					else
						speed=10;

					player_finish=1;
				}
				else
				{
					Draw_buffer.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());
					UI.read_From(Draw_buffer,12,0);
				}
			}
		}
		if(time_piece==99)
			time_piece=-1;
		clearScreen();
		Draw_UI();
		delay_ms(50);
		}
}


void manager::PlayerVsCPU()
{
	int score_add;
	int score_add_AI;
	int s;
	int r;
	int time_piece;					//时间碎片
	bool player_finish=1;				//玩家回合结束标志
	bool AI_finish=1;				//AI回合结束标志
	block obj_tmp_turn;				//转向假设
	block obj_tmp_x;				//横向假设
	block obj_tmp_y;				//纵向假设
	int mov_turn;
	int mov_x;
	piece GameLocation_tmp(20,10);			//假设游戏区
	int value_now=0;				//记录当前评价分
	int value_max=0;				//记录最高评价分
	int value_max_turn;
	int value_max_x;
	piece GameLocation_AI(20,10);
	piece Draw_buffer_AI(20,10);
	piece Imformation_AI(8,4);
	block obj_now_AI;
	block obj_next_AI;
	UI.clearPiece();
	score=0;
	score_2=0;

	srand((unsigned)time(NULL));
	r=(rand()%(99));
	obj_next.creatblock(r);
	r=(rand()%(99));
	obj_next_AI.creatblock(r);

	for(int i=2;i<17;i++)	//绘制外框
	{
		UI(i,20)=11;
	}
	for(int i=20;i<35;i++)	//绘制外框
	{
		UI(i,20)=11;
	}
	for(int j=4;j<20;j++)
	{
		UI(1,j)=12;UI(12,j)=12;UI(17,j)=12;UI(19,j)=12;UI(30,j)=12;UI(35,j)=12;
	}
	UI(1,20)=16;UI(12,20)=19;UI(17,20)=15;UI(19,20)=16;UI(30,20)=19;UI(35,20)=15;
	UI(13,16)=30;UI(14,16)=9;UI(15,16)=9;UI(16,16)=9;
	UI(13,18)=31;UI(14,18)=9;UI(15,18)=9;UI(16,18)=9;
	UI(12,10)=20;UI(17,10)=18;UI(12,15)=20;UI(13,15)=11;UI(14,15)=11;UI(15,15)=11;UI(16,15)=11;UI(17,15)=18;
	UI(30,10)=20;UI(35,10)=18;UI(30,15)=20;UI(31,15)=11;UI(32,15)=11;UI(33,15)=11;UI(34,15)=11;UI(35,15)=18;
	Imformation(0,4)=11;Imformation(1,4)=11;Imformation(2,4)=11;Imformation(3,4)=11;
	Imformation_AI(0,4)=11;Imformation_AI(1,4)=11;Imformation_AI(2,4)=11;Imformation_AI(3,4)=11;
	Imformation(0,5)=39;Imformation(1,5)=9;Imformation(2,5)=9;Imformation(3,5)=9;
	Imformation_AI(0,5)=40;Imformation_AI(1,5)=9;Imformation_AI(2,5)=9;Imformation_AI(3,5)=9;

	for(time_piece=0;/***/;time_piece++)
	{	
		for(int i=0;i<9;i++)	//检查是否GAMEOVER
		{
			if(GameLocation(i,3)!=0)	//PLAYER
			{
				Call_gameover(Draw_buffer);
				Draw_buffer.write_To(UI,2,0);
//				Call_win(Draw_buffer_AI);
//				Draw_buffer_AI.write_To(UI,20,0);
				clearScreen();
				Draw_UI();
				while(readKeyboard(1)!=LEAVE){}
				return;
			}
			if(GameLocation_AI(i,3)!=0)	//AI
			{
				Call_gameover(Draw_buffer_AI);
				Draw_buffer_AI.write_To(UI,20,0);
//				Call_win(Draw_buffer);
//				Draw_buffer.write_To(UI,2,0);
				clearScreen();
				Draw_UI();
				while(readKeyboard(1)!=LEAVE){}
				return;
			}
		}

		if(time_piece%4==0)			//AI的分割时间片
		{
			if(AI_finish==1)		//若一回合结束，AI则做好下一回合准备，并计算好预备放置点
			{
				obj_now_AI=obj_next_AI;
				r=(rand()%(99));
				obj_next_AI.creatblock(r);
				Imformation_AI.read_From(obj_NULL.getbox(),0,0);						//将未来积木，分数等投射到信息区上
				Imformation_AI.read_From(obj_next_AI.getbox(),obj_next_AI.getx()-3,0);
				Imformation_AI(0,7)=27;Imformation_AI(1,7)=9;Imformation_AI(2,7)=9;Imformation_AI(3,7)=29;
				UI.read_From(Imformation_AI,31,6);
				AI_finish=0;

				value_max=-100000;
				GameLocation_tmp=GameLocation_AI;
				obj_tmp_turn=obj_now_AI;
				for(mov_turn=0;mov_turn<4;mov_turn++)							//枚举旋转类型
				{
					obj_tmp_x=obj_tmp_turn;
					while(obj_tmp_x.move_lift(GameLocation_tmp)){}
					for(mov_x=obj_tmp_x.getx();/***/;mov_x++)	//枚举横向移动
					{
						obj_tmp_y=obj_tmp_x;
						while(obj_tmp_y.move_down(GameLocation_tmp)){}
						GameLocation_tmp.read_From_soft(obj_tmp_y.getbox(),mov_x,obj_tmp_y.gety());//固化此次枚举类型
						value_now=Evaluation(GameLocation_tmp);		//获取此枚举情况的评价
						if(value_now>value_max)						//根据评价值权衡操作
						{
							value_max=value_now;
							value_max_turn=mov_turn;
							value_max_x=mov_x;
						}
						GameLocation_tmp=GameLocation_AI;				//取消此次假设固化
						if(!obj_tmp_x.move_right(GameLocation_tmp))
							break;
					}
					obj_tmp_turn.turn(GameLocation_tmp);
				}

				continue;
				
			}
			else
			{
				Draw_buffer_AI.read_From(GameLocation_AI,0,0);
				if(value_max_turn!=0)
				{
					obj_now_AI.turn(GameLocation_AI);
					value_max_turn--;
				}
				else if(value_max_x-obj_now_AI.getx()>0)
				{
					obj_now_AI.move_right(GameLocation_AI);
					if(value_max_x-obj_now_AI.getx()>0)
						obj_now_AI.move_right(GameLocation_AI);
				}
				else if(obj_now_AI.getx()-value_max_x>0)
				{
					obj_now_AI.move_lift(GameLocation_AI);
					if(obj_now_AI.getx()-value_max_x>0)
						obj_now_AI.move_lift(GameLocation_AI);
				}
				else
				{
					obj_now_AI.move_down(GameLocation_AI);
					obj_now_AI.move_down(GameLocation_AI);
				}
				Draw_buffer_AI.read_From(GameLocation_AI,0,0);
				Draw_buffer_AI.read_From_soft(obj_now_AI.getbox(),obj_now_AI.getx(),obj_now_AI.gety());
				UI.read_From(Draw_buffer_AI,20,0);
				if(obj_now_AI.isTouch(GameLocation_AI))
				{
					GameLocation_AI.read_From_soft(obj_now_AI.getbox(),obj_now_AI.getx(),obj_now_AI.gety());
					score_add_AI=Offset(GameLocation_AI);				//判断消行，且获取消行数
					punish(GameLocation,score_add_AI);
					switch(score_add_AI)
					{
					case 1:
						score_2+=1;
						break;
					case 2:
						score_2+=3;
						break;
					case 3:
						score_2+=6;
						break;
					case 4:
						score_2+=10;
						break;
					default:
						break;
					}
					AI_finish=1;
				}
			}
		}
		else							//玩家时间碎片
		{
			if(player_finish==1)		//若一回合结束，则做好下一回合准备
			{
				obj_now=obj_next;
				r=(rand()%(99));
				obj_next.creatblock(r);
				Imformation.read_From(obj_NULL.getbox(),0,0);						//将未来积木，分数等投射到信息区上
				Imformation.read_From(obj_next.getbox(),obj_next.getx()-3,0);
				Imformation(0,7)=27;Imformation(1,7)=9;Imformation(2,7)=9;Imformation(3,7)=28;
				UI.read_From(Imformation,13,6);
				player_finish=0;
				continue;
			}
			else
			{
				for(int wait=0;wait<CATCH;wait++)
				{
					Draw_buffer.read_From(GameLocation,0,0);
					s=Frame();
					if(s==1)
					{
						Call_pause(Draw_buffer);
						Draw_buffer.write_To(UI,2,0);
						clearScreen();
						Draw_UI();
						while(readKeyboard(1)!=PAUSE){}
						continue;
					}
					else if(s==2)
					{
						Call_gameover(Draw_buffer);
						Draw_buffer.write_To(UI,2,0);
//						Call_win(Draw_buffer_AI);
//						Draw_buffer_AI.write_To(UI,20,0);
						clearScreen();
						Draw_UI();
						while(readKeyboard(1)!=LEAVE){}
						return;
					}
					else if(s==0)
					{
						Draw_buffer.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());//将当前方块位置软性投射到缓冲绘图区
						UI.read_From(Draw_buffer,2,0);			//将缓冲绘图区内容投射到界面上
					}
				}
				if((time_piece+1)%8==0)
				{
					if(!obj_now.move_down(GameLocation))
					{
						GameLocation.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());
						score_add=Offset(GameLocation);				//判断消行，且获取消行数
						punish(GameLocation_AI,score_add);
						switch(score_add)
						{
						case 1:
							score+=1;
							break;
						case 2:
							score+=3;
							break;
						case 3:
							score+=6;
							break;
						case 4:
							score+=10;
							break;
						default:
							break;
						}
						UI.read_From(GameLocation,2,0);
						player_finish=1;
					}
					else
					{
						Draw_buffer.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());
						UI.read_From(Draw_buffer,2,0);
					}
				}
			}
		}
		if(time_piece==99)
			time_piece=-1;
		clearScreen();
		Draw_UI();
		delay_ms(80);

	}
}

void manager::Multiplayer()
{
	piece choice(3,9);
	int ch=6;
	
	UI.clearPiece();
	for(int i=12;i<27;i++)	//绘制外框
	{
		UI(i,4)=11;UI(i,20)=11;
	}
	for(int j=5;j<20;j++)
	{
		UI(11,j)=12;UI(27,j)=12;
	}
	UI(11,4)=13;UI(27,4)=14;UI(11,20)=16;UI(27,20)=15;
	UI(16,7)=32;UI(17,7)=9;UI(18,7)=9;UI(19,7)=9;UI(20,7)=9;UI(21,7)=9;UI(22,7)=9;
	UI(16,9)=33;UI(17,9)=9;UI(18,9)=9;UI(19,9)=9;UI(20,9)=9;UI(21,9)=9;UI(22,9)=9;
	UI(16,11)=34;UI(17,11)=9;UI(18,11)=9;UI(19,11)=9;UI(20,11)=9;UI(21,11)=9;UI(22,11)=9;
	UI(16,13)=35;UI(17,13)=9;UI(18,13)=9;UI(19,13)=9;UI(20,13)=9;UI(21,13)=9;UI(22,13)=9;
	UI(16,17)=36;UI(17,17)=9;UI(18,17)=9;UI(19,17)=9;UI(20,17)=9;UI(21,17)=9;UI(22,17)=9;

	for(int i=1;i<8;i++)							//绘制选择框
	{
		choice(i,0)=11;
		choice(i,2)=11;
	}
	choice(0,0)=13;choice(8,0)=14;choice(8,2)=15;choice(0,2)=16;choice(0,1)=12;choice(8,1)=12;
	UI.clearPiece();
	for(int i=12;i<27;i++)	//绘制外框
	{
		UI(i,4)=11;UI(i,20)=11;
	}
	for(int j=5;j<20;j++)
	{
		UI(11,j)=12;UI(27,j)=12;
	}
	UI(11,4)=13;UI(27,4)=14;UI(11,20)=16;UI(27,20)=15;
	UI(16,7)=41;UI(17,7)=9;UI(18,7)=9;UI(19,7)=9;UI(20,7)=9;UI(21,7)=9;UI(22,7)=9;
	UI(16,11)=42;UI(17,11)=9;UI(18,11)=9;UI(19,11)=9;UI(20,11)=9;UI(21,11)=9;UI(22,11)=9;
	UI(16,17)=43;UI(17,17)=9;UI(18,17)=9;UI(19,17)=9;UI(20,17)=9;UI(21,17)=9;UI(22,17)=9;

	while(1)
	{
		UI.read_From_soft(choice,15,ch);					//选择框软性写入UI
		clearScreen();
		Draw_UI();
		int key;
		key=readKeyboard(1);
		if(key==DOWN)
		{
			if(ch==6)
				ch=10;
			else if(ch==10)
				ch=16;
			else
				ch=6;
			for(int n=15;n<24;n++)
			{
				UI(n,6)=0;UI(n,8)=0;UI(n,10)=0;UI(n,12)=0;UI(n,16)=0;UI(n,18)=0;
			}
			for(int m=6;m<19;m++)
			{
				UI(15,m)=0;UI(23,m)=0;
			}
			UI.read_From_soft(choice,15,ch);					//选择框软性写入UI
			clearScreen();
			Draw_UI();
		}
		else if(key==UP)
		{
			if(ch==6)
				ch=16;
			else if(ch==10)
				ch=6;
			else
				ch=10;
			for(int n=15;n<24;n++)
			{
				UI(n,6)=0;UI(n,8)=0;UI(n,10)=0;UI(n,12)=0;UI(n,16)=0;UI(n,18)=0;
			}
			for(int m=6;m<19;m++)
			{
				UI(15,m)=0;UI(23,m)=0;
			}
			UI.read_From_soft(choice,15,ch);					//选择框软性写入UI
			clearScreen();
			Draw_UI();
		}
		else if(key==LIFT||key==RIGHT||key==SPACE)
		{
			if(ch==6)
			{
				Server_game();
				return;
			}
			else if(ch==10)
			{
				Client_game();
				return;
			}
			else
				return;
		}
		else
			continue;
	}
}


void manager::Server_game()
{
	printf("                      wait for connection......\n");
	int sockfd,newsockfd;
	struct sockaddr_in addr;
	socklen_t addr_len = sizeof(struct sockaddr_in);
	sockfd = socket(AF_INET,SOCK_STREAM,0);
	bzero(&addr,sizeof(addr));
	addr.sin_family =AF_INET;
	addr.sin_port = htons(PORT);
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	bind(sockfd,(struct sockaddr*)&addr,sizeof(addr));
	listen(sockfd,3);
	newsockfd = accept (sockfd,(struct sockaddr*)&addr,&addr_len);

	int time_piece;
	int player_finish=0;
	int info_p1[256];							
	//第0标志位
	//第1位代表状态标志，传输暂停，胜负等信息
	//第2位代表obj_next类型
	//第3位代表分数
	//第4位代表消行数
	//第5位开始是画面信息
	int info_p2[256];
	int score_add=0;
	int r;
	int s;

	piece GameLocation_p2(20,10);			//p2游戏区
	piece Imformation_p2(8,4);
	block obj_next_p2;
	UI.clearPiece();
	score=0;
	score_2=0;
	info_p2[4]=0;

	srand((unsigned)time(NULL));
	r=(rand()%(99));
	obj_next.creatblock(r);

	for(int i=2;i<17;i++)	//绘制外框
	{
		UI(i,20)=11;
	}
	for(int i=20;i<35;i++)	//绘制外框
	{
		UI(i,20)=11;
	}
	for(int j=4;j<20;j++)
	{
		UI(1,j)=12;UI(12,j)=12;UI(17,j)=12;UI(19,j)=12;UI(30,j)=12;UI(35,j)=12;
	}
	UI(1,20)=16;UI(12,20)=19;UI(17,20)=15;UI(19,20)=16;UI(30,20)=19;UI(35,20)=15;
	UI(13,18)=31;UI(14,18)=9;UI(15,18)=9;UI(16,18)=9;
	UI(12,10)=20;UI(17,10)=18;UI(12,15)=20;UI(13,15)=11;UI(14,15)=11;UI(15,15)=11;UI(16,15)=11;UI(17,15)=18;
	UI(30,10)=20;UI(35,10)=18;UI(30,15)=20;UI(31,15)=11;UI(32,15)=11;UI(33,15)=11;UI(34,15)=11;UI(35,15)=18;
	Imformation(0,4)=11;Imformation(1,4)=11;Imformation(2,4)=11;Imformation(3,4)=11;
	Imformation_p2(0,4)=11;Imformation_p2(1,4)=11;Imformation_p2(2,4)=11;Imformation_p2(3,4)=11;
	Imformation(0,5)=44;Imformation(1,5)=9;Imformation(2,5)=9;Imformation(3,5)=9;
	Imformation_p2(0,5)=45;Imformation_p2(1,5)=9;Imformation_p2(2,5)=9;Imformation_p2(3,5)=9;

	Imformation.read_From(obj_NULL.getbox(),0,0);						//将未来积木，分数等投射到信息区上
	Imformation.read_From(obj_next.getbox(),obj_next.getx()-3,0);
	Imformation(0,7)=27;Imformation(1,7)=9;Imformation(2,7)=9;Imformation(3,7)=28;
	UI.read_From(Imformation,13,6);

	for(time_piece=0;/***/;time_piece++)
	{
		for(int i=0;i<9;i++)	//检查是否GAMEOVER
		{
			if(GameLocation(i,3)!=0)
			{
				Call_gameover(Draw_buffer);
				Draw_buffer.write_To(UI,2,0);
//				Call_win(GameLocation_p2);
//				GameLocation_p2.write_To(UI,20,0);
				clearScreen();
				Draw_UI();
				info_p1[1]=2;		//状态标志位
				write(newsockfd,info_p1,sizeof(info_p1));
				while(readKeyboard(1)!=LEAVE){}
				shutdown(newsockfd,2);
				return;
			}
		}
		read(newsockfd,info_p2,sizeof(info_p2));

		info_p1[0]=0;
		info_p1[1]=0;
		info_p1[2]=obj_next.gettype();
		info_p1[3]=score;
		info_p1[4]=score_add;
		int k;
		Draw_buffer.read_From(GameLocation,0,0);
		Draw_buffer.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());
		for(int j=0,k=5;j<20;j++)
		{
			for(int i=0;i<10;i++)
			{
				info_p1[k]=Draw_buffer(i,j);
				k++;
			}
		}
		write(newsockfd,info_p1,sizeof(info_p1));

		obj_next_p2.creatblock(info_p2[2]);
		score_2=info_p2[3];
		for(int j=0,k=5;j<20;j++)
		{
			for(int i=0;i<10;i++)
			{
				GameLocation_p2(i,j)=info_p2[k];
				k++;
			}
		}
		if(info_p2[1]==2)
		{
			Call_win(Draw_buffer);
			Draw_buffer.write_To(UI,2,0);
//			Call_gameover(GameLocation_p2);
//			GameLocation_p2.write_To(UI,20,0);
			clearScreen();
			Draw_UI();
			while(readKeyboard(1)!=LEAVE){}
			return;
		}
		punish(GameLocation,info_p2[4]);
		Imformation_p2.read_From(obj_NULL.getbox(),0,0);						//将未来积木，分数等投射到信息区上
		Imformation_p2.read_From(obj_next_p2.getbox(),obj_next_p2.getx()-3,0);
		Imformation_p2(0,7)=27;Imformation_p2(1,7)=9;Imformation_p2(2,7)=9;Imformation_p2(3,7)=29;
		UI.read_From(Imformation_p2,31,6);
		UI.read_From(GameLocation_p2,20,0);

		if(player_finish==1)		//若一回合结束，则做好下一回合准备
		{
			obj_now=obj_next;
			r=(rand()%(99));
			obj_next.creatblock(r);
			Imformation.read_From(obj_NULL.getbox(),0,0);						//将未来积木，分数等投射到信息区上
			Imformation.read_From(obj_next.getbox(),obj_next.getx()-3,0);
			Imformation(0,7)=27;Imformation(1,7)=9;Imformation(2,7)=9;Imformation(3,7)=28;
			UI.read_From(Imformation,13,6);
			score_add=0;
			player_finish=0;
			continue;
		}
		else
		{
			for(int wait=0;wait<CATCH;wait++)
			{
				Draw_buffer.read_From(GameLocation,0,0);
				s=Frame();
				if(s==2)
				{
					Call_gameover(Draw_buffer);
					Draw_buffer.write_To(UI,2,0);
//					Call_win(GameLocation_p2);
//					GameLocation_p2.write_To(UI,20,0);
					clearScreen();
					Draw_UI();
					info_p1[1]=2;		//状态标志位
					write(newsockfd,info_p1,sizeof(info_p1));
					while(readKeyboard(1)!=LEAVE){}
					shutdown(newsockfd,2);
					return;
				}
				else if(s==0)
				{
					Draw_buffer.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());//将当前方块位置软性投射到缓冲绘图区
					UI.read_From(Draw_buffer,2,0);			//将缓冲绘图区内容投射到界面上
				}
			}
			if((time_piece+1)%8==0)
			{
				if(!obj_now.move_down(GameLocation))
				{
					GameLocation.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());
					score_add=Offset(GameLocation);				//判断消行，且获取消行数
					switch(score_add)
					{
					case 1:
						score+=1;
						break;
					case 2:
						score+=3;
						break;
					case 3:
						score+=6;
						break;
					case 4:
						score+=10;
						break;
					default:
						break;
					}
					UI.read_From(GameLocation,2,0);
					player_finish=1;
				}
				else
				{
					score_add=0;
					Draw_buffer.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());
					UI.read_From(Draw_buffer,2,0);
				}
			}
		}
		if(time_piece==99)
			time_piece=-1;
		clearScreen();
		Draw_UI();
		delay_ms(50);

	}
}

void manager::Client_game()
{
	char ip[20];
	printf("                      Input the IP you want to connect:\n");
	printf("                      ");
	scanf("%s",ip);
	int newsockfd;
	struct sockaddr_in addr;
	bzero(&addr,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port=htons(PORT);
	addr.sin_addr.s_addr = inet_addr(ip);

	newsockfd=socket(AF_INET,SOCK_STREAM,0);
	if(connect(newsockfd,(struct sockaddr*)&addr,sizeof(addr))<0)
		return;

	int time_piece;
	int player_finish=1;
	int info_p1[256];
	int info_p2[256];
	int score_add=0;
	int r;
	int s;

	piece GameLocation_p2(20,10);			//p2游戏区
	piece Imformation_p2(8,4);
	block obj_next_p2;
	UI.clearPiece();
	score=0;
	score_2=0;
	info_p2[4]=0;

	srand((unsigned)time(NULL));
	r=(rand()%(99));
	obj_next.creatblock(r);

	for(int i=2;i<17;i++)	//绘制外框
	{
		UI(i,20)=11;
	}
	for(int i=20;i<35;i++)	//绘制外框
	{
		UI(i,20)=11;
	}
	for(int j=4;j<20;j++)
	{
		UI(1,j)=12;UI(12,j)=12;UI(17,j)=12;UI(19,j)=12;UI(30,j)=12;UI(35,j)=12;
	}
	UI(1,20)=16;UI(12,20)=19;UI(17,20)=15;UI(19,20)=16;UI(30,20)=19;UI(35,20)=15;
	UI(13,18)=31;UI(14,18)=9;UI(15,18)=9;UI(16,18)=9;
	UI(12,10)=20;UI(17,10)=18;UI(12,15)=20;UI(13,15)=11;UI(14,15)=11;UI(15,15)=11;UI(16,15)=11;UI(17,15)=18;
	UI(30,10)=20;UI(35,10)=18;UI(30,15)=20;UI(31,15)=11;UI(32,15)=11;UI(33,15)=11;UI(34,15)=11;UI(35,15)=18;
	Imformation(0,4)=11;Imformation(1,4)=11;Imformation(2,4)=11;Imformation(3,4)=11;
	Imformation_p2(0,4)=11;Imformation_p2(1,4)=11;Imformation_p2(2,4)=11;Imformation_p2(3,4)=11;
	Imformation(0,5)=44;Imformation(1,5)=9;Imformation(2,5)=9;Imformation(3,5)=9;
	Imformation_p2(0,5)=45;Imformation_p2(1,5)=9;Imformation_p2(2,5)=9;Imformation_p2(3,5)=9;
	Imformation.read_From(obj_NULL.getbox(),0,0);								//将未来积木，分数等投射到信息区上
	Imformation.read_From(obj_next.getbox(),obj_next.getx()-3,0);
	Imformation(0,7)=27;Imformation(1,7)=9;Imformation(2,7)=9;Imformation(3,7)=28;
	UI.read_From(Imformation,13,6);

	for(time_piece=0;/***/;time_piece++)
	{
		for(int i=0;i<9;i++)	//检查是否GAMEOVER
		{
			if(GameLocation(i,3)!=0)	//PLAYER
			{
				Call_gameover(Draw_buffer);
				Draw_buffer.write_To(UI,2,0);
//				Call_win(GameLocation_p2);
//				GameLocation_p2.write_To(UI,20,0);
				clearScreen();
				Draw_UI();
				info_p1[1]=2;		//状态标志位
				write(newsockfd,info_p1,sizeof(info_p1));
				while(readKeyboard(1)!=LEAVE){}
				shutdown(newsockfd,2);
				return;
			}
		}

		info_p1[0]=0;
		info_p1[1]=0;
		info_p1[2]=obj_next.gettype();
		info_p1[3]=score;
		info_p1[4]=score_add;
		int k;
		Draw_buffer.read_From(GameLocation,0,0);
		Draw_buffer.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());
		for(int j=0,k=5;j<20;j++)
		{
			for(int i=0;i<10;i++)
			{
				info_p1[k]=Draw_buffer(i,j);
				k++;
			}
		}
		write(newsockfd,info_p1,sizeof(info_p1));
		
		read(newsockfd,info_p2,sizeof(info_p2));
		obj_next_p2.creatblock(info_p2[2]);
		score_2=info_p2[3];
		for(int j=0,k=5;j<20;j++)
		{
			for(int i=0;i<10;i++)
			{
				GameLocation_p2(i,j)=info_p2[k];
				k++;
			}
		}
		if(info_p2[1]==2)
		{
			Call_win(Draw_buffer);
			Draw_buffer.write_To(UI,2,0);
//			Call_gameover(GameLocation_p2);
//			GameLocation_p2.write_To(UI,20,0);
			clearScreen();
			Draw_UI();
			while(readKeyboard(1)!=LEAVE){}
			return;
		}

		punish(GameLocation,info_p2[4]);
		Imformation_p2.read_From(obj_NULL.getbox(),0,0);						//将未来积木，分数等投射到信息区上
		Imformation_p2.read_From(obj_next_p2.getbox(),obj_next_p2.getx()-3,0);
		Imformation_p2(0,7)=27;Imformation_p2(1,7)=9;Imformation_p2(2,7)=9;Imformation_p2(3,7)=29;
		UI.read_From(Imformation_p2,31,6);
		UI.read_From(GameLocation_p2,20,0);

		if(player_finish==1)		//若一回合结束，则做好下一回合准备
		{
			obj_now=obj_next;
			r=(rand()%(99));
			obj_next.creatblock(r);
			Imformation.read_From(obj_NULL.getbox(),0,0);						//将未来积木，分数等投射到信息区上
			Imformation.read_From(obj_next.getbox(),obj_next.getx()-3,0);
			Imformation(0,7)=27;Imformation(1,7)=9;Imformation(2,7)=9;Imformation(3,7)=28;
			UI.read_From(Imformation,13,6);
			score_add=0;
			player_finish=0;
			continue;
		}
		else
		{
			for(int wait=0;wait<CATCH;wait++)
			{
				Draw_buffer.read_From(GameLocation,0,0);
				s=Frame();
				if(s==2)
				{
					Call_gameover(Draw_buffer);
					Draw_buffer.write_To(UI,2,0);
//					Call_win(GameLocation_p2);
//					GameLocation_p2.write_To(UI,20,0);
					clearScreen();
					Draw_UI();
					info_p1[1]=2;		//状态标志位
					write(newsockfd,info_p1,sizeof(info_p1));
					while(readKeyboard(1)!=LEAVE){}
					shutdown(newsockfd,2);
					return;
				}
				else if(s==0)
				{
					Draw_buffer.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());//将当前方块位置软性投射到缓冲绘图区
					UI.read_From(Draw_buffer,2,0);			//将缓冲绘图区内容投射到界面上
				}
			}
			if((time_piece+1)%8==0)
			{
				if(!obj_now.move_down(GameLocation))
				{
					GameLocation.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());
					score_add=Offset(GameLocation);				//判断消行，且获取消行数
					switch(score_add)
					{
					case 1:
						score+=1;
						break;
					case 2:
						score+=3;
						break;
					case 3:
						score+=6;
						break;
					case 4:
						score+=10;
						break;
					default:
						break;
					}
					UI.read_From(GameLocation,2,0);
					player_finish=1;
				}
				else
				{
					score_add=0;
					Draw_buffer.read_From_soft(obj_now.getbox(),obj_now.getx(),obj_now.gety());
					UI.read_From(Draw_buffer,2,0);
				}
			}
		}
		if(time_piece==99)
			time_piece=-1;
		clearScreen();
		Draw_UI();
		delay_ms(50);

	}
}


void manager::Draw_UI() const
{
	for(int j=0;j<21;j++)
	{
		for(int i=0;i<38;i++)
		{
			if(UI(i,j)<11)
			{
				if(UI(i,j)==0)
					printf("  ");
				else if(UI(i,j)==1)
					printf("\033[36m█▋\033[0m");
				else if(UI(i,j)==2)
					printf("\033[31m█▋\033[0m");
				else if(UI(i,j)==3)
					printf("\033[33m█▋\033[0m");
				else if(UI(i,j)==4)
					printf("\033[32;1m█▋\033[0m");
				else if(UI(i,j)==5)
					printf("\033[34;1m█▋\033[0m");
				else if(UI(i,j)==6)
					printf("\033[32m█▋\033[0m");
				else if(UI(i,j)==7)
					printf("\033[34m█▋\033[0m");
				else if(UI(i,j)==8)
					printf("\033[37m█▋\033[0m");
				else if(UI(i,j)==9)
					continue;
				else if(UI(i,j)==10)
					printf(" ");
			}
			else if(UI(i,j)<21)
			{
				if(UI(i,j)==11)
					printf("\033[35m━━\033[0m");
				else if(UI(i,j)==12)
					printf("\033[35m┃┃\033[0m");
				else if(UI(i,j)==13)
					printf("\033[35m┏┳\033[0m");
				else if(UI(i,j)==14)
					printf("\033[35m┳┓\033[0m");
				else if(UI(i,j)==15)
					printf("\033[35m┻┛\033[0m");
				else if(UI(i,j)==16)
					printf("\033[35m┗┻\033[0m");
				else if(UI(i,j)==17)
					printf("\033[35m┳┳\033[0m");
				else if(UI(i,j)==18)
					printf("\033[35m┫┃\033[0m");
				else if(UI(i,j)==19)
					printf("\033[35m┻┻\033[0m");
				else if(UI(i,j)==20)
					printf("\033[35m┃┣\033[0m");
			}
			else
			{
				if(UI(i,j)==21)
					printf("\033[32;1mGameOver\033[0m");
				else if(UI(i,j)==22)
					printf("\033[31;1mYou Win!\033[0m");
				else if(UI(i,j)==23)
					printf("\033[34;1m Pause! \033[0m");
				else if(UI(i,j)==24)
					printf("\033[33;1mSpeed \033[0m");
				else if(UI(i,j)==25)
					printf("%2d",speed);
				else if(UI(i,j)==26)
					printf("MX");
				else if(UI(i,j)==27)
					printf("\033[31;1mres\033[0m");
				else if(UI(i,j)==28)
					printf("%5d",score);
				else if(UI(i,j)==29)
					printf("%5d",score_2);
				else if(UI(i,j)==30)
					printf("\033[34;1m P \033[0masue ");
				else if(UI(i,j)==31)
					printf("\033[32;1m L \033[0meave ");
				else if(UI(i,j)==32)
					printf("\033[31;1m    AIshow    \033[0m");
				else if(UI(i,j)==33)
					printf("\033[32;1m Singleplayer \033[0m");
				else if(UI(i,j)==34)
					printf("\033[33;1m Player vs AI \033[0m");
				else if(UI(i,j)==35)
					printf("\033[34;1m Multiplayer  \033[0m");
				else if(UI(i,j)==36)
					printf("\033[37;1m     Exit     \033[0m");
				else if(UI(i,j)==37)
					printf("Time");
				else if(UI(i,j)==38)
					printf("%4d",sec);
				else if(UI(i,j)==39)
					printf("\033[42m Player \033[0m");
				else if(UI(i,j)==40)
					printf("\033[41m  A  I  \033[0m");
				else if(UI(i,j)==41)
					printf("\033[31;1mCreat New Game\033[0m");
				else if(UI(i,j)==42)
					printf("\033[32;1m  Join a Game \033[0m");
				else if(UI(i,j)==43)
					printf("\033[37;1m    Cancel    \033[0m");
				else if(UI(i,j)==44)
					printf("\033[42mPlayer 1\033[0m");
				else if(UI(i,j)==45)
					printf("\033[41mPlayer 2\033[0m");
					
			}
		}
		printf("\n");
	}
}

int manager::Frame()
{
	int key;
	key=readKeyboard(0);
	switch(key)
	{
	case UP:
		obj_now.turn(GameLocation);
		break;
	case DOWN:
		obj_now.move_down(GameLocation);
		break;
	case LIFT:
		obj_now.move_lift(GameLocation);
		break;
	case RIGHT:
		obj_now.move_right(GameLocation);
		break;
	case SPACE:
		while(obj_now.move_down(GameLocation)){}
		break;
	case PAUSE:
		return 1;
		break;
	case LEAVE:
		return 2;
		break;
	default:
		return 3;
	}
	return 0;
}

int manager::Offset(piece & GameLocation)
{
	int count=0;
	int i,j;
	for(j=19;j>=0;j--)
	{
		for(i=0;i<10;i++)				//行扫描
			if(GameLocation(i,j)==0)		//若有一格空格则退出行扫描
				break;
		if(i==10)							//若整行都无空格
		{
			for(int n=j;n>=0;n--)
				for(int m=0;m<10;m++)
					GameLocation(m,n)=GameLocation(m,n-1);
			for(int m=0;m<10;m++)
				GameLocation(m,0)=0;
			j++;							//注意，若消去一行，下一次扫描需要从移下的这行开始
			count++;
		}
	}
	return count;
}

void manager::punish(piece & tar,int n)
{
	if(n<2)
		return;
	n=n-2;
	for(int j=n;j<20;j++)
		for(int i=0;i<10;i++)
			tar(i,j-n)=tar(i,j);
	for(int j=19-n+1;n>0;n--,j++)
		for(int i=0;i<10;i++)	
			tar(i,j)=((i+(tar(0,19-n)!=8))%2)*8;	
}

int manager::Evaluation(piece & tmp)
{
	int offset_count=0;		//消行数
	int high_max=0;			//最高高度数
	int high_every[10]={0};		//综合高度数
	int high_sum=0;			//全局高度数
	int smooth[10]={0};		//平整度,即相邻两列的高度差
	int smooth_sum=0;		//全局平整度
	int bubble_count=0;		//气泡数
	int bubble_count_2=0;		//单列气泡数
	int bubble_deep=0;		//气泡埋藏深度
	int v;
	int i,j,k;

	for(j=19;j>=0;j--)
	{
		for(i=0;i<10;i++)	
			if(tmp(i,j)==0)
				break;
		if(i==10)				//消行
		{

			for(int n=j;n>=0;n--)
				for(int m=0;m<10;m++)
					tmp(m,n)=tmp(m,n-1);
			for(int m=0;m<10;m++)
				tmp(m,0)=0;

			offset_count++;		//获取消行数
		}
	}

	for(i=0;i<10;i++)
	{
		for(j=0;j<20;j++)
		{
			if(tmp(i,j)>0)
			{
				if(high_max<20-j)
					high_max=20-j;			//记录最高高
				high_every[i]=20-j;			//记录综合高度
				for(k=1,bubble_count_2=0;j+k<20;k++)
				{
					if(tmp(i,j+k)==0)
					{
						bubble_count_2++;//气泡统计
						bubble_count++;
					}
				}
				if(bubble_count_2>0)
					bubble_deep+=k-bubble_count_2;//气泡深度
				break;
			}
		}
	}
	if(high_max>18)
		return -100000;
	bubble_count=bubble_count>0?bubble_count+1:0;	
	for(i=0;i<10;i++)				//求全局高度数
		high_sum+=high_every[i];
	for(i=0;i<9;i++)				//求全局平整度
	{
		smooth[i]=(high_every[i]-high_every[i+1]>0)?(high_every[i]-high_every[i+1]):(high_every[i+1]-high_every[i]);
		smooth_sum+=smooth[i]*(smooth[i]-1);
	}
	v=offset_count*offset_count*10-high_sum-smooth_sum-high_max*high_max*2-bubble_count*bubble_count*8-bubble_deep*8;
	return v;
}

void manager::Call_gameover(piece & tar)
{
	for(int i=0;i<6;i++)	//绘制图案
	{
		Interruption(i,0)=11;
		Interruption(i,2)=11;
	}
	Interruption(0,1)=12;
	Interruption(5,1)=12;
	Interruption(0,0)=13;
	Interruption(5,0)=14;
	Interruption(5,2)=15;
	Interruption(0,2)=16;
	Interruption(1,1)=21;
	Interruption(2,1)=9;
	Interruption(3,1)=9;
	Interruption(4,1)=9;

	Interruption.write_To(tar,2,9);		//将此图投影到界面上
}


void manager::Call_win(piece & tar)
{
	for(int i=0;i<6;i++)	//绘制图案
	{
		Interruption(i,0)=11;
		Interruption(i,2)=11;
	}
	Interruption(0,1)=12;
	Interruption(5,1)=12;
	Interruption(0,0)=13;
	Interruption(5,0)=14;
	Interruption(5,2)=15;
	Interruption(0,2)=16;
	Interruption(1,1)=22;
	Interruption(2,1)=9;
	Interruption(3,1)=9;
	Interruption(4,1)=9;
	Interruption.write_To(tar,2,9);		//将此图投影到界面上
}

void manager::Call_pause(piece & tar)
{
	for(int i=0;i<6;i++)	//绘制图案
	{
		Interruption(i,0)=11;
		Interruption(i,2)=11;
	}
	Interruption(0,1)=12;
	Interruption(5,1)=12;
	Interruption(0,0)=13;
	Interruption(5,0)=14;
	Interruption(5,2)=15;
	Interruption(0,2)=16;
	Interruption(1,1)=23;

	Interruption(2,1)=9;
	Interruption(3,1)=9;
	Interruption(4,1)=9;
	Interruption.write_To(tar,2,9);		//将此图投影到界面上
}



